/*
 * Copyright 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package androidx.compose.runtime.snapshots

import kotlin.random.Random
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue

class SnapshotIdSetTests {
    @Test
    fun emptySetShouldBeEmpty() {
        val empty = SnapshotIdSet.EMPTY

        repeat(1000) {
            empty.shouldBe(it, false)
        }
    }

    @Test
    fun shouldBeAbleToSetItems() {
        val times = 10000
        val set = (0..times).fold(SnapshotIdSet.EMPTY) { prev, index ->
            prev.set(index)
        }

        repeat(times) {
            set.shouldBe(it, true)
        }
    }

    @Test
    fun shouldBeAbleToSetOnlyEven() {
        val times = 10000
        val set = (0..times).fold(SnapshotIdSet.EMPTY) { prev, index ->
            if (index % 2 == 0) prev.set(index) else prev
        }

        repeat(times) {
            set.shouldBe(it, it % 2 == 0)
        }
    }

    @Test
    fun shouldBeAbleToSetOnlyOdds() {
        val times = 10000
        val set = (0..times).fold(SnapshotIdSet.EMPTY) { prev, index ->
            if (index % 2 == 1) prev.set(index) else prev
        }

        repeat(times) {
            set.shouldBe(it, it % 2 == 1)
        }
    }

    @Test
    fun shouldBeAbleToClearEvens() {
        val times = 10000
        val allSet = (0..times).fold(SnapshotIdSet.EMPTY) { prev, index ->
            prev.set(index)
        }

        val set = (0..times).fold(allSet) { prev, index ->
            if (index % 2 == 0) prev.clear(index) else prev
        }

        repeat(times - 1) {
            set.shouldBe(it, it % 2 == 1)
        }
    }

    @Test
    fun shouldBeAbleToCrawlSet() {
        val times = 10000
        val set = (0..times).fold(SnapshotIdSet.EMPTY) { prev, index ->
            prev.clear(index - 1).set(index)
        }

        set.shouldBe(times, true)
        repeat(times - 1) {
            set.shouldBe(it, false)
        }
    }

    @Test
    fun shouldBeAbleToCrawlAndClear() {
        val times = 10000
        val set = (0..times).fold(SnapshotIdSet.EMPTY) { prev, index ->
            prev.let {
                if ((index - 1) % 33 != 0) it.clear(index - 1) else it
            }.set(index)
        }

        set.shouldBe(times, true)

        // The multiples of 33 items should now be set
        repeat(times - 1) {
            set.shouldBe(it, it % 33 == 0)
        }

        val newSet = (0 until times).fold(set) { prev, index ->
            prev.clear(index)
        }

        newSet.shouldBe(times, true)

        repeat(times - 1) {
            newSet.shouldBe(it, false)
        }
    }

    @Test
    fun shouldBeAbleToInsertAndRemoveOutOfOptimalRange() {
        SnapshotIdSet.EMPTY
            .set(1000)
            .set(1)
            .shouldBe(1000, true)
            .shouldBe(1, true)
            .set(10)
            .shouldBe(10, true)
            .set(4)
            .shouldBe(4, true)
            .clear(1)
            .shouldBe(1, false)
            .clear(4)
            .shouldBe(4, false)
            .clear(10)
            .shouldBe(1, false)
            .shouldBe(4, false)
            .shouldBe(10, false)
            .shouldBe(1000, true)
    }

    @Test
    fun shouldMatchBooleanArray() {
        val random = Random(10)
        val booleans = BooleanArray(1000)
        val set = (0..100).fold(SnapshotIdSet.EMPTY) { prev, _ ->
            val value = random.nextInt(0, 1000)
            booleans[value] = true
            prev.set(value)
        }

        val clear = (0..100).fold(set) { prev, _ ->
            val value = random.nextInt(0, 1000)
            booleans[value] = false
            prev.clear(value)
        }

        repeat(1000) {
            clear.shouldBe(it, booleans[it])
        }
    }

    @Test
    fun shouldBeAbleToAndNotBits() {
        val random = Random(11)
        val booleans = BooleanArray(1000)
        val setA = (0..100).fold(SnapshotIdSet.EMPTY) { prev, _ ->
            val value = random.nextInt(0, 1000)
            booleans[value] = true
            prev.set(value)
        }

        val setB = (0..100).fold(SnapshotIdSet.EMPTY) { prev, _ ->
            val value = random.nextInt(0, 1000)
            booleans[value] = false
            prev.set(value)
        }

        val set = setA.andNot(setB)
        repeat(1000) {
            set.shouldBe(it, booleans[it])
        }
    }

    @Test
    fun shouldBeAbleToAndNot() {
        fun test(size: Int) {
            val random = Random(size)
            val booleans = BooleanArray(1024)
            val setA = (0 until size).fold(SnapshotIdSet.EMPTY) { prev, index ->
                if (random.nextInt(0, 1000) > 500) {
                    booleans[index] = true
                    prev.set(index)
                } else prev
            }
            val setB = (0 until size).fold(SnapshotIdSet.EMPTY) { prev, index ->
                if (random.nextInt(0, 1000) > 500) {
                    booleans[index] = false
                    prev.set(index)
                } else prev
            }
            val set = setA.andNot(setB)
            repeat(size) {
                set.shouldBe(it, booleans[it])
            }
        }
        test(32)
        test(64)
        test(128)
        test(512)
        test(1024)
    }

    @Test
    fun shouldBeAbleToOr() {
        fun test(size: Int) {
            val random = Random(size)
            val booleans = BooleanArray(1024)
            val setA = (0 until size).fold(SnapshotIdSet.EMPTY) { prev, index ->
                if (random.nextInt(0, 1000) > 500) {
                    booleans[index] = true
                    prev.set(index)
                } else prev
            }
            val setB = (0 until size).fold(SnapshotIdSet.EMPTY) { prev, index ->
                if (random.nextInt(0, 1000) > 500) {
                    booleans[index] = true
                    prev.set(index)
                } else prev
            }
            val set = setA.or(setB)
            repeat(size) {
                set.shouldBe(it, booleans[it])
            }
        }
        test(32)
        test(64)
        test(128)
        test(512)
        test(1024)
    }

    @Test
    fun shouldBeAbleToIterate() {
        fun test(size: Int) {
            val random = Random(size)
            val values = mutableListOf<Int>()
            val set = (0 until size).fold(SnapshotIdSet.EMPTY) { prev, index ->
                if (random.nextInt(0, 1000) > 500) {
                    values.add(index)
                    prev.set(index)
                } else prev
            }
            values.zip(set).forEach {
                assertEquals(it.first, it.second)
            }
            assertEquals(values.size, set.count())
        }

        test(64)
        test(128)
        test(512)
        test(1024)
    }

    @Test // Regression b/182822837
    fun shouldReportTheCorrectLowest() {
        fun test(number: Int) {
            val set = SnapshotIdSet.EMPTY.set(number)
            assertEquals(number, set.lowest(-1))
        }

        repeat(64) {
            test(it)
        }
    }

    @Test // Regression: b/147836978
    fun shouldValidWhenSetIsLarge() {
        val data = """
2:true,
2:false,
3:true,
3:false,
4:true,
4:false,
5:true,
5:false,
6:true,
6:false,
7:true,
7:false,
8:true,
8:false,
9:true,
9:false,
10:true,
10:false,
11:true,
11:false,
12:true,
12:false,
13:true,
13:false,
14:true,
14:false,
15:true,
15:false,
16:true,
16:false,
17:true,
17:false,
18:true,
18:false,
19:true,
19:false,
20:true,
20:false,
21:true,
21:false,
22:true,
22:false,
23:true,
23:false,
24:true,
24:false,
25:true,
25:false,
26:true,
26:false,
27:true,
27:false,
28:true,
28:false,
29:true,
29:false,
30:true,
30:false,
31:true,
31:false,
32:true,
32:false,
33:true,
33:false,
34:true,
34:false,
35:true,
35:false,
36:true,
36:false,
37:true,
37:false,
38:true,
38:false,
39:true,
39:false,
40:true,
40:false,
41:true,
41:false,
42:true,
42:false,
43:true,
43:false,
44:true,
44:false,
45:true,
45:false,
46:true,
46:false,
47:true,
47:false,
48:true,
48:false,
49:true,
49:false,
50:true,
50:false,
51:true,
51:false,
52:true,
52:false,
53:true,
53:false,
54:true,
54:false,
55:true,
55:false,
56:true,
56:false,
57:true,
57:false,
58:true,
58:false,
59:true,
59:false,
60:true,
60:false,
61:true,
61:false,
62:true,
62:false,
63:true,
63:false,
64:true,
64:false,
65:true,
65:false,
66:true,
66:false,
67:true,
67:false,
68:true,
68:false,
69:true,
69:false,
70:true,
70:false,
71:true,
71:false,
72:true,
72:false,
73:true,
73:false,
74:true,
74:false,
75:true,
75:false,
76:true,
76:false,
77:true,
77:false,
78:true,
78:false,
79:true,
79:false,
80:true,
80:false,
81:true,
81:false,
82:true,
82:false,
83:true,
83:false,
84:true,
84:false,
85:true,
85:false,
86:true,
86:false,
87:true,
87:false,
88:true,
88:false,
89:true,
89:false,
90:true,
90:false,
91:true,
91:false,
92:true,
92:false,
93:true,
93:false,
94:true,
94:false,
95:true,
95:false,
96:true,
96:false,
97:true,
97:false,
98:true,
98:false,
99:true,
99:false,
100:true,
100:false,
101:true,
101:false,
102:true,
102:false,
103:true,
103:false,
104:true,
104:false,
105:true,
105:false,
106:true,
106:false,
107:true,
107:false,
108:true,
108:false,
109:true,
109:false,
110:true,
110:false,
111:true,
111:false,
112:true,
112:false,
113:true,
113:false,
114:true,
114:false,
115:true,
115:false,
116:true,
116:false,
117:true,
117:false,
118:true,
118:false,
119:true,
119:false,
120:true,
120:false,
121:true,
121:false,
122:true,
122:false,
123:true,
123:false,
124:true,
124:false,
125:true,
125:false,
126:true,
126:false,
127:true,
127:false,
128:true,
128:false,
129:true,
129:false,
130:true,
130:false,
131:true,
131:false,
132:true,
132:false,
133:true,
133:false,
134:true,
134:false,
135:true,
135:false,
136:true,
136:false,
137:true,
137:false,
138:true,
138:false,
139:true,
139:false,
140:true,
140:false,
141:true,
141:false,
142:true,
142:false,
143:true,
143:false,
144:true,
144:false,
145:true,
145:false,
146:true,
146:false,
147:true,
147:false,
148:true,
148:false,
149:true,
149:false,
150:true,
150:false,
151:true,
151:false,
152:true,
152:false,
153:true,
153:false,
154:true,
154:false,
155:true,
155:false,
156:true,
156:false,
157:true,
157:false,
158:true,
158:false,
159:true,
159:false,
160:true,
160:false,
161:true,
161:false,
162:true,
162:false,
163:true,
163:false,
164:true,
164:false,
165:true,
165:false,
166:true,
166:false,
167:true,
167:false,
168:true,
168:false,
169:true,
169:false,
170:true,
170:false,
171:true,
171:false,
172:true,
172:false,
173:true,
173:false,
174:true,
174:false,
175:true,
175:false,
176:true,
176:false,
177:true,
177:false,
178:true,
178:false,
179:true,
179:false,
180:true,
180:false,
181:true,
181:false,
182:true,
182:false,
183:true,
183:false,
184:true,
184:false,
185:true,
185:false,
186:true,
186:false,
187:true,
187:false,
188:true,
188:false,
189:true,
189:false,
190:true,
190:false,
191:true,
191:false,
192:true,
192:false,
193:true,
193:false,
194:true,
194:false,
195:true,
195:false,
196:true,
196:false,
197:true,
197:false,
198:true,
198:false,
199:true,
199:false,
200:true,
200:false,
201:true,
201:false,
202:true,
202:false,
203:true,
203:false,
204:true,
204:false,
205:true,
205:false,
206:true,
206:false,
207:true,
207:false,
208:true,
208:false,
209:true,
209:false,
210:true,
210:false,
211:true,
211:false,
212:true,
212:false,
213:true,
213:false,
214:true,
214:false,
215:true,
215:false,
216:true,
216:false,
217:true,
217:false,
218:true,
218:false,
219:true,
219:false,
220:true,
220:false,
221:true,
221:false,
222:true,
222:false,
223:true,
223:false,
224:true,
224:false,
225:true,
225:false,
226:true,
226:false,
227:true,
227:false,
228:true,
228:false,
229:true,
229:false,
230:true,
230:false,
231:true,
231:false,
232:true,
232:false,
233:true,
233:false,
234:true,
234:false,
235:true,
235:false,
236:true,
236:false,
237:true,
237:false,
238:true,
238:false,
239:true,
239:false,
240:true,
240:false,
241:true,
241:false,
242:true,
242:false,
243:true,
243:false,
244:true,
244:false,
245:true,
245:false,
246:true,
246:false,
247:true,
247:false,
248:true,
248:false,
249:true,
249:false,
250:true,
250:false,
251:true,
251:false,
252:true,
252:false,
253:true,
253:false,
254:true,
254:false,
255:true,
255:false,
256:true,
256:false,
257:true,
257:false,
258:true,
258:false,
259:true,
259:false,
260:true,
260:false,
261:true,
261:false,
262:true,
262:false,
263:true,
263:false,
264:true,
264:false,
265:true,
265:false,
266:true,
266:false,
267:true,
267:false,
268:true,
268:false,
269:true,
269:false,
270:true,
270:false,
271:true,
271:false,
272:true,
272:false,
273:true,
273:false,
274:true,
274:false,
275:true,
275:false,
276:true,
276:false,
277:true,
277:false,
278:true,
278:false,
279:true,
279:false,
280:true,
280:false,
281:true,
281:false,
282:true,
282:false,
283:true,
283:false,
284:true,
284:false,
285:true,
285:false,
286:true,
286:false,
287:true,
287:false,
288:true,
288:false,
289:true,
289:false,
290:true,
290:false,
291:true,
291:false,
292:true,
292:false,
293:true,
293:false,
294:true,
294:false,
295:true,
295:false,
296:true,
296:false,
297:true,
297:false,
298:true,
298:false,
299:true,
299:false,
300:true,
300:false,
301:true,
301:false,
302:true,
302:false,
303:true,
303:false,
304:true,
304:false,
305:true,
305:false,
306:true,
306:false,
307:true,
307:false,
308:true,
308:false,
309:true,
309:false,
310:true,
310:false,
311:true,
311:false,
312:true,
312:false,
313:true,
313:false,
314:true,
314:false,
315:true,
315:false,
316:true,
316:false,
317:true,
317:false,
318:true,
318:false,
319:true,
319:false,
320:true,
320:false,
321:true,
321:false,
322:true,
322:false,
323:true,
323:false,
324:true,
324:false,
325:true,
325:false,
326:true,
326:false,
327:true,
327:false,
328:true,
328:false,
329:true,
329:false,
330:true,
330:false,
331:true,
331:false,
332:true,
332:false,
333:true,
333:false,
334:true,
334:false,
335:true,
335:false,
336:true,
336:false,
337:true,
337:false,
338:true,
338:false,
339:true,
339:false,
340:true,
340:false,
341:true,
341:false,
342:true,
342:false,
343:true,
343:false,
344:true,
344:false,
345:true,
345:false,
346:true,
346:false,
347:true,
347:false,
348:true,
348:false,
349:true,
349:false,
350:true,
350:false,
351:true,
351:false,
352:true,
352:false,
353:true,
353:false,
354:true,
354:false,
355:true,
355:false,
356:true,
356:false,
357:true,
357:false,
358:true,
358:false,
359:true,
359:false,
360:true,
360:false,
361:true,
361:false,
362:true,
362:false,
363:true,
363:false,
364:true,
364:false,
365:true,
365:false,
366:true,
366:false,
367:true,
367:false,
368:true,
368:false,
369:true,
369:false,
370:true,
370:false,
371:true,
371:false,
372:true,
372:false,
373:true,
373:false,
374:true,
374:false,
375:true,
375:false,
376:true,
376:false,
377:true,
377:false,
378:true,
378:false,
379:true,
379:false,
380:true,
380:false,
381:true,
381:false,
382:true,
382:false,
383:true,
383:false,
384:true,
384:false,
385:true,
385:false,
386:true,
386:false,
387:true,
387:false,
388:true,
388:false,
389:true,
389:false,
390:true,
390:false,
391:true,
391:false,
392:true,
392:false,
393:true,
393:false,
394:true,
394:false,
395:true,
395:false,
396:true,
396:false,
397:true,
397:false,
398:true,
398:false,
399:true,
399:false,
400:true,
400:false,
401:true,
401:false,
402:true,
402:false,
403:true,
403:false,
404:true,
404:false,
405:true,
405:false,
406:true,
406:false,
407:true,
407:false,
408:true,
408:false,
409:true,
409:false,
410:true,
410:false,
411:true,
411:false,
412:true,
412:false,
413:true,
413:false,
414:true,
414:false,
415:true,
415:false,
416:true,
416:false,
417:true,
417:false,
418:true,
418:false,
419:true,
419:false,
420:true,
420:false,
421:true,
421:false,
422:true,
422:false,
423:true,
423:false,
424:true,
424:false,
425:true,
425:false,
426:true,
426:false,
427:true,
427:false,
428:true,
428:false,
429:true,
429:false,
430:true,
430:false,
431:true,
431:false,
432:true,
432:false,
433:true,
433:false,
434:true,
434:false,
435:true,
435:false,
436:true,
436:false,
437:true,
437:false,
438:true,
438:false,
439:true,
439:false,
440:true,
440:false,
441:true,
441:false,
442:true,
442:false,
443:true,
443:false,
444:true,
444:false,
445:true,
445:false,
446:true,
446:false,
447:true,
447:false,
448:true,
448:false,
449:true,
449:false,
450:true,
450:false,
451:true,
451:false,
452:true,
452:false,
453:true,
453:false,
454:true,
454:false,
455:true,
455:false,
456:true,
456:false,
457:true,
457:false,
458:true,
458:false,
459:true,
459:false,
460:true,
460:false,
461:true,
461:false,
462:true,
462:false,
463:true,
463:false,
464:true,
464:false,
465:true,
465:false,
466:true,
466:false,
467:true,
467:false,
468:true,
468:false,
469:true,
469:false,
470:true,
470:false,
471:true,
471:false,
472:true,
472:false,
473:true,
473:false,
474:true,
474:false,
475:true,
475:false,
476:true,
476:false,
477:true,
477:false,
478:true,
478:false,
479:true,
479:false,
480:true,
480:false,
481:true,
481:false,
482:true,
482:false,
483:true,
483:false,
484:true,
484:false,
485:true,
485:false,
486:true,
486:false,
487:true,
487:false,
488:true,
488:false,
489:true,
489:false,
490:true,
490:false,
491:true,
491:false,
492:true,
492:false,
493:true,
493:false,
494:true,
494:false,
495:true,
495:false,
496:true,
496:false,
497:true,
497:false,
498:true,
498:false,
499:true,
499:false,
500:true,
500:false,
501:true,
501:false,
502:true,
502:false,
503:true,
503:false,
504:true,
504:false,
505:true,
505:false,
506:true,
506:false,
507:true,
507:false,
508:true,
508:false,
509:true,
509:false,
510:true,
510:false,
511:true,
511:false,
512:true,
512:false,
513:true,
513:false,
514:true,
514:false,
515:true,
515:false,
516:true,
516:false,
517:true,
517:false,
518:true,
518:false,
519:true,
519:false,
520:true,
520:false,
521:true,
521:false,
522:true,
522:false,
523:true,
523:false,
524:true,
524:false,
525:true,
525:false,
526:true,
526:false,
527:true,
527:false,
528:true,
528:false,
529:true,
529:false,
530:true,
530:false,
531:true,
531:false,
532:true,
532:false,
533:true,
533:false,
534:true,
534:false,
535:true,
535:false,
536:true,
536:false,
537:true,
537:false,
538:true,
538:false,
539:true,
539:false,
540:true,
540:false,
541:true,
541:false,
542:true,
542:false,
543:true,
543:false,
544:true,
544:false,
545:true,
545:false,
546:true,
546:false,
547:true,
547:false,
548:true,
548:false,
549:true,
549:false,
550:true,
550:false,
551:true,
551:false,
552:true,
552:false,
553:true,
553:false,
554:true,
554:false,
555:true,
555:false,
556:true,
556:false,
557:true,
557:false,
558:true,
558:false,
559:true,
559:false,
560:true,
560:false,
561:true,
561:false,
562:true,
562:false,
563:true,
563:false,
564:true,
565:true,
565:false,
564:false,
566:true,
566:false,
567:true,
567:false,
568:true,
568:false,
569:true,
569:false,
570:true,
570:false,
571:true,
571:false,
572:true,
572:false,
573:true,
573:false,
574:true,
574:false,
575:true,
575:false,
576:true,
576:false,
577:true,
577:false,
578:true,
578:false,
579:true,
579:false,
580:true,
580:false,
581:true,
581:false,
582:true,
582:false,
583:true,
583:false,
584:true,
584:false,
585:true,
585:false,
586:true,
586:false,
587:true,
587:false,
588:true,
588:false,
589:true,
589:false,
590:true,
590:false,
591:true,
591:false,
592:true,
592:false,
593:true,
593:false,
594:true,
594:false,
595:true,
595:false,
596:true,
596:false,
597:true,
597:false,
598:true,
598:false,
599:true,
599:false,
600:true,
600:false,
601:true,
601:false,
602:true,
603:true,
603:false,
602:false,
604:true,
604:false,
605:true,
605:false,
606:true,
606:false,
607:true,
607:false,
608:true,
608:false,
609:true,
609:false,
610:true,
610:false,
611:true,
611:false,
612:true,
612:false,
613:true,
613:false,
614:true,
614:false,
615:true,
615:false,
616:true,
616:false,
617:true,
617:false,
618:true,
618:false,
619:true,
619:false,
620:true,
620:false,
621:true,
621:false,
622:true,
622:false,
623:true,
623:false,
624:true,
624:false,
625:true,
625:false,
626:true,
626:false,
627:true,
627:false,
628:true,
628:false,
629:true,
629:false,
630:true,
630:false,
631:true,
631:false,
632:true,
632:false,
633:true,
633:false,
634:true,
634:false,
635:true,
635:false,
636:true,
636:false,
637:true,
637:false,
638:true,
638:false,
639:true,
639:false,
640:true,
640:false,
641:true,
641:false,
642:true,
642:false,
643:true,
643:false,
644:true,
644:false,
645:true,
645:false,
646:true,
646:false,
647:true,
647:false,
648:true,
648:false,
649:true,
649:false,
650:true,
650:false,
651:true,
651:false,
652:true,
652:false,
653:true,
653:false,
654:true,
654:false,
655:true,
655:false,
656:true,
656:false,
657:true,
657:false,
658:true,
658:false,
659:true,
659:false,
660:true,
660:false,
661:true,
661:false,
662:true,
662:false,
663:true,
663:false,
664:true,
664:false,
665:true,
665:false,
666:true,
666:false,
667:true,
667:false,
668:true,
668:false,
669:true,
669:false,
670:true,
670:false,
671:true,
671:false,
672:true,
672:false,
673:true,
673:false,
674:true,
675:true,
675:false,
674:false,
676:true,
676:false,
677:true,
677:false,
678:true,
678:false,
679:true,
679:false,
680:true,
680:false,
681:true,
681:false,
682:true,
682:false,
683:true,
683:false,
684:true,
684:false,
685:true,
685:false,
686:true,
686:false,
687:true,
687:false,
688:true,
688:false,
689:true,
689:false,
690:true,
690:false,
691:true,
691:false,
692:true,
692:false,
693:true,
693:false,
694:true,
694:false,
695:true,
695:false,
696:true,
696:false,
697:true,
697:false,
698:true,
698:false,
699:true,
699:false,
700:true,
700:false,
701:true,
701:false,
702:true,
702:false,
703:true,
703:false,
704:true,
704:false,
705:true,
705:false,
706:true,
706:false,
707:true,
707:false,
708:true,
708:false,
709:true,
709:false,
710:true,
710:false,
711:true,
711:false,
712:true,
712:false,
713:true,
713:false,
714:true,
714:false,
715:true,
715:false,
716:true,
716:false,
717:true,
717:false,
718:true,
718:false,
719:true,
719:false,
720:true,
720:false,
721:true,
721:false,
722:true,
722:false,
723:true,
723:false,
724:true,
724:false,
725:true,
725:false,
726:true,
726:false,
727:true,
727:false,
728:true,
728:false,
729:true,
729:false,
730:true,
730:false,
731:true,
731:false,
732:true,
732:false,
733:true,
733:false,
734:true,
734:false,
735:true,
735:false,
736:true,
736:false,
737:true,
737:false,
738:true,
738:false,
739:true,
739:false,
740:true,
740:false,
741:true,
741:false,
742:true,
742:false,
743:true,
743:false,
744:true,
744:false,
745:true,
745:false,
746:true,
746:false,
747:true,
747:false,
748:true,
749:true,
749:false,
750:true,
750:false,
751:true,
751:false,
748:false,
752:true,
752:false,
753:true,
753:false,
754:true,
754:false,
755:true,
755:false,
756:true,
756:false,
757:true,
757:false,
758:true,
758:false,
759:true,
759:false,
760:true,
760:false,
761:true,
761:false,
762:true,
762:false,
763:true,
763:false,
764:true,
764:false,
765:true,
765:false,
766:true,
766:false,
767:true,
767:false,
768:true,
768:false,
769:true,
769:false,
770:true,
770:false,
771:true,
771:false,
772:true,
772:false,
773:true,
773:false,
774:true,
774:false,
775:true,
775:false,
776:true,
776:false,
777:true,
777:false,
778:true,
778:false,
779:true,
779:false,
780:true,
780:false,
781:true,
781:false,
782:true,
782:false,
783:true,
783:false,
784:true,
784:false,
785:true,
785:false,
786:true,
786:false,
787:true,
787:false,
788:true,
788:false,
789:true,
789:false,
790:true,
790:false,
791:true,
791:false,
792:true,
792:false,
793:true,
793:false,
794:true,
794:false,
795:true,
795:false,
796:true,
796:false,
797:true,
797:false,
798:true,
798:false,
799:true,
799:false,
800:true,
800:false,
801:true,
801:false,
802:true,
802:false,
803:true,
803:false,
804:true,
804:false,
805:true,
805:false,
806:true,
806:false,
807:true,
807:false,
808:true,
808:false,
809:true,
809:false,
810:true,
810:false,
811:true,
811:false,
812:true,
812:false,
813:true,
813:false,
814:true,
814:false,
815:true,
815:false,
816:true,
816:false,
817:true,
817:false,
818:true,
818:false,
819:true,
819:false,
820:true,
820:false,
821:true,
821:false,
822:true,
822:false,
823:true,
823:false,
824:true,
824:false,
825:true,
825:false,
826:true,
826:false,
827:true,
827:false,
828:true,
828:false,
829:true,
829:false,
830:true,
830:false,
831:true,
831:false,
832:true,
832:false,
833:true,
833:false,
834:true,
834:false,
835:true,
835:false,
836:true,
836:false,
837:true,
837:false,
838:true,
838:false,
839:true,
839:false,
840:true,
840:false,
841:true,
841:false,
842:true,
842:false,
843:true,
843:false,
844:true,
844:false,
845:true,
845:false,
846:true,
846:false,
847:true,
847:false,
848:true,
848:false,
849:true,
849:false,
850:true,
850:false,
851:true,
851:false,
852:true,
852:false,
853:true,
853:false,
854:true,
854:false,
855:true,
855:false,
856:true,
856:false,
857:true,
857:false,
858:true,
858:false,
859:true,
859:false,
860:true,
860:false,
861:true,
861:false,
862:true,
862:false,
863:true,
863:false,
864:true,
864:false,
865:true,
865:false,
866:true,
866:false,
867:true,
867:false,
868:true,
868:false,
869:true,
869:false,
870:true,
870:false,
871:true,
871:false,
872:true,
872:false,
873:true,
873:false,
874:true,
874:false,
875:true,
875:false,
876:true,
876:false,
877:true,
877:false,
878:true,
878:false,
879:true,
879:false,
880:true,
880:false,
881:true,
881:false,
882:true,
882:false,
883:true,
883:false,
884:true,
884:false,
885:true,
885:false,
886:true,
886:false,
887:true,
887:false,
888:true,
888:false,
889:true,
889:false,
890:true,
890:false,
891:true,
891:false,
892:true,
892:false,
893:true,
893:false,
894:true,
894:false,
895:true,
895:false,
896:true,
896:false,
897:true,
897:false,
898:true,
898:false,
899:true,
899:false,
900:true,
900:false,
901:true,
901:false,
902:true,
902:false,
903:true,
903:false,
904:true,
904:false,
905:true,
905:false,
906:true,
906:false,
907:true,
907:false,
908:true,
908:false,
909:true,
909:false,
910:true,
910:false,
911:true,
911:false,
912:true,
912:false,
913:true,
913:false,
914:true,
914:false,
915:true,
915:false,
916:true,
916:false,
917:true,
917:false,
918:true,
918:false,
919:true,
919:false,
920:true,
920:false,
921:true,
921:false,
922:true,
922:false,
923:true,
923:false,
924:true,
924:false,
925:true,
925:false,
926:true,
926:false,
927:true,
927:false,
928:true,
928:false,
929:true,
929:false,
930:true,
930:false,
931:true,
931:false,
932:true,
932:false,
933:true,
933:false,
934:true,
934:false,
935:true,
935:false,
936:true,
936:false,
937:true,
937:false,
938:true,
938:false,
939:true,
939:false,
940:true,
940:false,
941:true,
941:false,
942:true,
942:false,
943:true,
943:false,
944:true,
944:false,
945:true,
945:false,
946:true,
946:false,
947:true,
947:false,
948:true,
948:false,
949:true,
949:false,
950:true,
950:false,
951:true,
951:false,
952:true,
952:false,
953:true,
953:false,
954:true,
954:false,
955:true,
955:false,
956:true,
956:false,
957:true,
957:false,
958:true,
958:false,
959:true,
959:false,
960:true,
960:false,
961:true,
961:false,
962:true,
962:false,
963:true,
963:false,
964:true,
964:false,
965:true,
965:false,
966:true,
966:false,
967:true,
967:false,
968:true,
968:false,
969:true,
969:false,
970:true,
970:false,
971:true,
971:false,
972:true,
972:false,
973:true,
973:false,
974:true,
974:false,
975:true,
975:false,
976:true,
976:false,
977:true,
977:false,
978:true,
978:false,
979:true,
979:false,
980:true,
980:false,
981:true,
981:false,
982:true,
982:false,
983:true,
983:false,
984:true,
984:false,
985:true,
985:false,
986:true,
986:false,
987:true,
987:false,
988:true,
988:false,
989:true,
989:false,
990:true,
990:false,
991:true,
991:false,
992:true,
992:false,
993:true,
993:false,
994:true,
994:false,
995:true,
995:false,
996:true,
996:false,
997:true,
997:false,
998:true,
998:false,
999:true,
999:false,
1000:true,
1000:false,
1001:true,
1001:false,
1002:true,
1002:false,
1003:true,
1003:false,
1004:true,
1004:false,
1005:true,
1005:false,
1006:true,
1006:false,
1007:true,
1007:false,
1008:true,
1008:false,
1009:true,
1009:false,
1010:true,
1010:false,
1011:true,
1011:false,
1012:true,
1012:false,
1013:true,
1013:false,
1014:true,
1014:false,
1015:true,
1015:false,
1016:true,
1016:false,
1017:true,
1017:false,
1018:true,
1018:false,
1019:true,
1019:false,
1020:true,
1020:false,
1021:true,
1021:false,
1022:true,
1022:false,
1023:true,
1023:false,
1024:true,
1024:false,
1025:true,
1025:false,
1026:true,
1026:false,
1027:true,
1027:false,
1028:true,
1028:false,
1029:true,
1029:false,
1030:true,
1030:false,
1031:true,
1031:false,
1032:true,
1032:false,
1033:true,
1033:false,
1034:true,
1034:false,
1035:true,
1035:false,
1036:true,
1036:false,
1037:true,
1037:false,
1038:true,
1038:false,
1039:true,
1039:false,
1040:true,
1040:false,
1041:true,
1041:false,
1042:true,
1042:false,
1043:true,
1043:false,
1044:true,
1044:false,
1045:true,
1045:false,
1046:true,
1046:false,
1047:true,
1047:false,
1048:true,
1048:false,
1049:true,
1049:false,
1050:true,
1050:false,
1051:true,
1051:false,
1052:true,
1052:false,
1053:true,
1053:false,
1054:true,
1054:false,
1055:true,
1055:false,
1056:true,
1056:false,
1057:true,
1057:false,
1058:true,
1058:false,
1059:true,
1059:false,
1060:true,
1060:false,
1061:true,
1061:false,
1062:true,
1062:false,
1063:true,
1063:false,
1064:true,
1064:false,
1065:true,
1065:false,
1066:true,
1066:false,
1067:true,
1067:false,
1068:true,
1068:false,
1069:true,
1069:false,
1070:true,
1070:false,
1071:true,
1071:false,
1072:true,
1072:false,
1073:true,
1073:false,
1074:true,
1074:false,
1075:true,
1075:false,
1076:true,
1076:false,
1077:true,
1077:false,
1078:true,
1078:false,
1079:true,
1079:false,
1080:true,
1080:false,
1081:true,
1081:false,
1082:true,
1082:false,
1083:true,
1083:false,
1084:true,
1084:false,
1085:true,
1085:false,
1086:true,
1086:false,
1087:true,
1087:false,
1088:true,
1088:false,
1089:true,
1089:false,
1090:true,
1090:false,
1091:true,
1091:false,
1092:true,
1092:false,
1093:true,
1093:false,
1094:true,
1094:false,
1095:true,
1095:false,
1096:true,
1096:false,
1097:true,
1097:false,
1098:true,
1098:false,
1099:true,
1099:false,
1100:true,
1100:false,
1101:true,
1101:false,
1102:true,
1102:false,
1103:true,
1103:false,
1104:true,
1104:false,
1105:true,
1105:false,
1106:true,
1106:false,
1107:true,
1107:false,
1108:true,
1108:false,
1109:true,
1109:false,
1110:true,
1110:false,
1111:true,
1111:false,
1112:true,
1112:false,
1113:true,
1113:false,
1114:true,
1114:false,
1115:true,
1115:false,
1116:true,
1116:false,
1117:true,
1117:false,
1118:true,
1118:false,
1119:true,
1119:false,
1120:true,
1120:false,
1121:true,
1121:false,
1122:true,
1122:false,
1123:true,
1123:false,
1124:true,
1124:false,
1125:true,
1125:false,
1126:true,
1126:false,
1127:true,
1127:false,
1128:true,
1128:false,
1129:true,
1129:false,
1130:true,
1130:false,
1131:true,
1131:false,
1132:true,
1132:false,
1133:true,
1133:false,
1134:true,
1134:false,
1135:true,
1135:false,
1136:true,
1136:false,
1137:true,
1137:false,
1138:true,
1138:false,
1139:true,
1139:false,
1140:true,
1140:false,
1141:true,
1141:false,
1142:true,
1142:false,
1143:true,
1143:false,
1144:true,
1144:false,
1145:true,
1145:false,
1146:true,
1146:false,
1147:true,
1147:false,
1148:true,
1148:false,
1149:true,
1149:false,
1150:true,
1150:false,
1151:true,
1151:false,
1152:true,
1152:false,
1153:true,
1153:false,
1154:true,
1154:false,
1155:true,
1155:false,
1156:true,
1156:false,
1157:true,
1157:false,
1158:true,
1158:false,
1159:true,
1159:false,
1160:true,
1160:false,
1161:true,
1161:false,
1162:true,
1162:false,
1163:true,
1163:false,
1164:true,
1164:false,
1165:true,
1165:false,
1166:true,
1166:false,
1167:true,
1167:false,
1168:true,
1168:false,
1169:true,
1169:false,
1170:true,
1170:false,
1171:true,
1171:false,
1172:true,
1172:false,
1173:true,
1173:false,
1174:true,
1174:false,
1175:true,
1175:false,
1176:true,
1176:false,
1177:true,
1177:false,
1178:true,
1178:false,
1179:true,
1179:false,
1180:true,
1180:false,
1181:true,
1181:false,
1182:true,
1182:false,
1183:true,
1183:false,
1184:true,
1184:false,
1185:true,
1185:false,
1186:true,
1186:false,
1187:true,
1187:false,
1188:true,
1188:false,
1189:true,
1189:false,
1190:true,
1190:false,
1191:true,
1191:false,
1192:true,
1192:false,
1193:true,
1193:false,
1194:true,
1194:false,
1195:true,
1195:false,
1196:true,
1196:false,
1197:true,
1197:false,
1198:true,
1198:false,
1199:true,
1199:false,
1200:true,
1200:false,
1201:true,
1201:false,
1202:true,
1202:false,
1203:true,
1203:false,
1204:true,
1204:false,
1205:true,
1205:false,
1206:true,
1206:false,
1207:true,
1207:false,
1208:true,
1208:false,
1209:true,
1209:false,
1210:true,
1210:false,
1211:true,
1211:false,
1212:true,
1212:false,
1213:true,
1213:false,
1214:true,
1214:false,
1215:true,
1215:false,
1216:true,
1216:false,
1217:true,
1217:false,
1218:true,
1218:false,
1219:true,
1219:false,
1220:true,
1220:false,
1221:true,
1221:false,
1222:true,
1222:false,
1223:true,
1223:false,
1224:true,
1224:false,
1225:true,
1225:false,
1226:true,
1226:false,
1227:true,
1227:false,
1228:true,
1228:false,
1229:true,
1229:false,
1230:true,
1230:false,
1231:true,
1231:false,
1232:true,
1232:false,
1233:true,
1233:false,
1234:true,
1234:false,
1235:true,
1235:false,
1236:true,
1236:false,
1237:true,
1237:false,
1238:true,
1238:false,
1239:true,
1239:false,
1240:true,
1240:false,
1241:true,
1241:false,
1242:true,
1242:false,
1243:true,
1243:false,
1244:true,
1244:false,
1245:true,
1245:false,
1246:true,
1246:false,
1247:true,
1247:false,
1248:true,
1248:false,
1249:true,
1249:false,
1250:true,
1250:false,
1251:true,
1251:false,
1252:true,
1252:false,
1253:true,
1253:false,
1254:true,
1254:false,
1255:true,
1255:false,
1256:true,
1256:false,
1257:true,
1257:false,
1258:true,
1258:false,
1259:true,
1259:false,
1260:true,
1260:false,
1261:true,
1261:false,
1262:true,
1262:false,
1263:true,
1263:false,
1264:true,
1264:false,
1265:true,
1265:false,
1266:true,
1266:false,
1267:true,
1267:false,
1268:true,
1268:false,
1269:true,
1269:false,
1270:true,
1270:false,
1271:true,
1271:false,
1272:true,
1272:false,
1273:true,
1273:false,
1274:true,
1274:false,
1275:true,
1275:false,
1276:true,
1276:false,
1277:true,
1277:false,
1278:true,
1278:false,
1279:true,
1279:false,
1280:true,
1280:false,
1281:true,
1281:false,
1282:true,
1282:false,
1283:true,
1283:false,
1284:true,
1284:false,
1285:true,
1285:false,
1286:true,
1286:false,
1287:true,
1287:false,
1288:true,
1288:false,
1289:true,
1289:false,
1290:true,
1290:false,
1291:true,
1291:false,
1292:true,
1292:false,
1293:true,
1293:false,
1294:true,
1294:false,
1295:true,
1295:false,
1296:true,
1296:false,
1297:true,
1297:false,
1298:true,
1298:false,
1299:true,
1299:false,
1300:true,
1300:false,
1301:true,
1301:false,
1302:true,
1302:false,
1303:true,
1303:false,
1304:true,
1304:false,
1305:true,
1305:false,
1306:true,
1306:false,
1307:true,
1307:false,
1308:true,
1308:false,
1309:true,
1309:false,
1310:true,
1310:false,
1311:true,
1311:false,
1312:true,
1312:false,
1313:true,
1313:false,
1314:true,
1314:false,
1315:true,
1315:false,
1316:true,
1316:false,
1317:true,
1317:false,
1318:true,
1318:false,
1319:true,
1319:false,
1320:true,
1320:false,
1321:true,
1321:false,
1322:true,
1322:false,
1323:true,
1323:false,
1324:true,
1324:false,
1325:true,
1325:false,
1326:true,
1326:false,
1327:true,
1327:false,
1328:true,
1328:false,
1329:true,
1329:false,
1330:true,
1330:false,
1331:true,
1331:false,
1332:true,
1332:false,
1333:true,
1333:false,
1334:true,
1334:false,
1335:true,
1335:false,
1336:true,
1336:false,
1337:true,
1337:false,
1338:true,
1338:false,
1339:true,
1339:false,
1340:true,
1340:false,
1341:true,
1341:false,
1342:true,
1342:false,
1343:true,
1343:false,
1344:true,
1344:false,
1345:true,
1345:false,
1346:true,
1346:false,
1347:true,
1347:false,
1348:true,
1348:false,
1349:true,
1349:false,
1350:true,
1350:false,
1351:true,
1351:false,
1352:true,
1352:false,
1353:true,
1353:false,
1354:true,
1354:false,
1355:true,
1355:false,
1356:true,
1356:false,
1357:true,
1357:false,
1358:true,
1358:false,
1359:true,
1359:false,
1360:true,
1360:false,
1361:true,
1361:false,
1362:true,
1362:false,
1363:true,
1363:false,
1364:true,
1364:false,
1365:true,
1365:false,
1366:true,
1366:false,
1367:true,
1367:false,
1368:true,
1368:false,
1369:true,
1369:false,
1370:true,
1370:false,
1371:true,
1371:false,
1372:true,
1372:false,
1373:true,
1373:false,
1374:true,
1374:false,
1375:true,
1375:false,
1376:true,
1376:false,
1377:true,
1377:false,
1378:true,
1378:false,
1379:true,
1379:false,
1380:true,
1380:false,
1381:true,
1381:false,
1382:true,
1382:false,
1383:true,
1383:false,
1384:true,
1384:false,
1385:true,
1385:false,
1386:true,
1386:false,
1387:true,
1387:false,
1388:true,
1388:false,
1389:true,
1389:false,
1390:true,
1390:false,
1391:true,
1391:false,
1392:true,
1392:false,
1393:true,
1393:false,
1394:true,
1394:false,
1395:true,
1395:false,
1396:true,
1396:false,
1397:true,
1397:false,
1398:true,
1398:false,
1399:true,
1399:false,
1400:true,
1400:false,
1401:true,
1401:false,
1402:true,
1402:false,
1403:true,
1403:false,
1404:true,
1404:false,
1405:true,
1405:false,
1406:true,
1406:false,
1407:true,
1407:false,
1408:true,
1408:false,
1409:true,
1409:false,
1410:true,
1410:false,
1411:true,
1411:false,
1412:true,
1412:false,
1413:true,
1413:false,
1414:true,
1414:false,
1415:true,
1415:false,
1416:true,
1416:false,
1417:true,
1417:false,
1418:true,
1418:false,
1419:true,
1419:false,
1420:true,
1420:false,
1421:true,
1421:false,
1422:true,
1422:false,
1423:true,
1423:false,
1424:true,
1424:false,
1425:true,
1425:false,
1426:true,
1426:false,
1427:true,
1427:false,
1428:true,
1428:false,
1429:true,
1429:false,
1430:true,
1430:false,
1431:true,
1431:false,
1432:true,
1432:false,
1433:true,
1433:false,
1434:true,
1434:false,
1435:true,
1435:false,
1436:true,
1436:false,
1437:true,
1437:false,
1438:true,
1438:false,
1439:true,
1439:false,
1440:true,
1440:false,
1441:true,
1441:false,
1442:true,
1442:false,
1443:true,
1443:false,
1444:true,
1444:false,
1445:true,
1445:false,
1446:true,
1446:false,
1447:true,
1447:false,
1448:true,
1448:false,
1449:true,
1449:false,
1450:true,
1450:false,
1451:true,
1451:false,
1452:true,
1452:false,
1453:true,
1453:false,
1454:true,
1454:false,
1455:true,
1455:false,
1456:true,
1456:false,
1457:true,
1457:false,
1458:true,
1458:false,
1459:true,
1459:false,
1460:true,
1460:false,
1461:true,
1461:false,
1462:true,
1462:false,
1463:true,
1463:false,
1464:true,
1464:false,
1465:true,
1465:false,
1466:true,
1466:false,
1467:true,
1467:false,
1468:true,
1468:false,
1469:true,
1469:false,
1470:true,
1470:false,
1471:true,
1471:false,
1472:true,
1472:false,
1473:true,
1473:false,
1474:true,
1474:false,
1475:true,
1475:false,
1476:true,
1476:false,
1477:true,
1477:false,
1478:true,
1478:false,
1479:true,
1479:false,
1480:true,
1480:false,
1481:true,
1481:false,
1482:true,
1482:false,
1483:true,
1483:false,
1484:true,
1484:false,
1485:true,
1485:false,
1486:true,
1486:false,
1487:true,
1487:false,
1488:true,
1488:false,
1489:true,
1489:false,
1490:true,
1490:false,
1491:true,
1491:false,
1492:true,
1492:false,
1493:true,
1493:false,
1494:true,
1494:false,
1495:true,
1495:false,
1496:true,
1496:false,
1497:true,
1497:false,
1498:true,
1498:false,
1499:true,
1499:false,
1500:true,
1500:false,
1501:true,
1501:false,
1502:true,
1502:false,
1503:true,
1503:false,
1504:true,
1504:false,
1505:true,
1505:false,
1506:true,
1506:false,
1507:true,
1507:false,
1508:true,
1508:false,
1509:true,
1509:false,
1510:true,
1510:false,
1511:true,
1511:false,
1512:true,
1512:false,
1513:true,
1513:false,
1514:true,
1514:false,
1515:true,
1515:false,
1516:true,
1516:false,
1517:true,
1517:false,
1518:true,
1518:false,
1519:true,
1519:false,
1520:true,
1520:false,
1521:true,
1521:false,
1522:true,
1522:false,
1523:true,
1523:false,
1524:true,
1524:false,
1525:true,
1525:false,
1526:true,
1526:false,
1527:true,
1527:false,
1528:true,
1528:false,
1529:true,
1529:false,
1530:true,
1530:false,
1531:true,
1531:false,
1532:true,
1532:false,
1533:true,
1533:false,
1534:true,
1534:false,
1535:true,
1535:false,
1536:true,
1536:false,
1537:true,
1537:false,
1538:true,
1538:false,
1539:true,
1539:false,
1540:true,
1540:false,
1541:true,
1541:false,
1542:true,
1542:false,
1543:true,
1543:false,
1544:true,
1544:false,
1545:true,
1545:false,
1546:true,
1546:false,
1547:true,
1547:false,
1548:true,
1548:false,
1549:true,
1549:false,
1550:true,
1550:false,
1551:true,
1551:false,
1552:true,
1552:false,
1553:true,
1553:false,
1554:true,
1554:false,
1555:true,
1555:false,
1556:true,
1556:false,
1557:true,
1557:false,
1558:true,
1558:false,
1559:true,
1559:false,
1560:true,
1560:false,
1561:true,
1561:false,
1562:true,
1562:false,
1563:true,
1563:false,
1564:true,
1564:false,
1565:true,
1565:false,
1566:true,
1566:false,
1567:true,
1567:false,
1568:true,
1568:false,
1569:true,
1569:false,
1570:true,
1570:false,
1571:true,
1571:false,
1572:true,
1572:false,
1573:true,
1573:false,
1574:true,
1574:false,
1575:true,
1575:false,
1576:true,
1576:false,
1577:true,
1577:false,
1578:true,
1578:false,
1579:true,
1579:false,
1580:true,
1580:false,
1581:true,
1581:false,
1582:true,
1582:false,
1583:true,
1584:true,
1584:false,
1583:false,
1585:true,
1585:false,
1586:true,
1586:false,
1587:true,
1587:false,
1588:true,
1588:false,
1589:true,
1589:false,
1590:true,
1590:false,
1591:true,
1591:false,
1592:true,
1592:false,
1593:true,
1593:false,
1594:true,
1594:false,
1595:true,
1595:false,
1596:true,
1596:false,
1597:true,
1597:false,
1598:true,
1598:false,
1599:true,
1599:false,
1600:true,
1600:false,
1601:true,
1601:false,
1602:true,
1602:false,
1603:true,
1603:false,
1604:true,
1604:false,
1605:true,
1605:false,
1606:true,
1606:false,
1607:true,
1607:false,
1608:true,
1608:false,
1609:true,
1609:false,
1610:true,
1610:false,
1611:true,
1611:false,
1612:true,
1612:false,
1613:true,
1613:false,
1614:true,
1614:false,
1615:true,
1615:false,
1616:true,
1616:false,
1617:true,
1617:false,
1618:true,
1618:false,
1619:true,
1619:false,
1620:true,
1620:false,
1621:true,
1621:false,
1622:true,
1622:false,
1623:true,
1624:true,
1624:false,
1623:false,
1625:true,
1625:false,
1626:true,
1626:false,
1627:true,
1627:false,
1628:true,
1628:false,
1629:true,
1629:false,
1630:true,
1630:false,
1631:true,
1631:false,
1632:true,
1632:false,
1633:true,
1633:false,
1634:true,
1634:false,
1635:true,
1635:false,
1636:true,
1636:false,
1637:true,
1637:false,
1638:true,
1638:false,
1639:true,
1639:false,
1640:true,
1640:false,
1641:true,
1641:false,
1642:true,
1642:false,
1643:true,
1643:false,
1644:true,
1644:false,
1645:true,
1645:false,
1646:true,
1646:false,
1647:true,
1647:false,
1648:true,
1648:false,
1649:true,
1649:false,
1650:true,
1650:false,
1651:true,
1651:false,
1652:true,
1652:false,
1653:true,
1653:false,
1654:true,
1654:false,
1655:true,
1656:true,
1656:false,
1655:false,
1657:true,
1657:false,
1658:true,
1658:false,
1659:true,
1659:false,
1660:true,
1660:false,
1661:true,
1661:false,
1662:true,
1662:false,
1663:true,
1663:false,
1664:true,
1664:false,
1665:true,
1665:false,
1666:true,
1666:false,
1667:true,
1667:false,
1668:true,
1668:false,
1669:true,
1669:false,
1670:true,
1670:false,
1671:true,
1671:false,
1672:true,
1672:false,
1673:true,
1673:false,
1674:true,
1674:false,
1675:true,
1675:false,
1676:true,
1676:false,
1677:true,
1677:false,
1678:true,
1678:false,
1679:true,
1679:false,
1680:true,
1680:false,
1681:true,
1681:false,
1682:true,
1682:false,
1683:true,
1683:false,
1684:true,
1684:false,
1685:true,
1685:false,
1686:true,
1686:false,
1687:true,
1687:false,
1688:true,
1688:false,
1689:true,
1689:false,
1690:true,
1690:false,
1691:true,
1691:false,
1692:true,
1692:false,
1693:true,
1694:true,
1694:false,
1693:false,
1695:true,
1695:false,
1696:true,
1696:false,
1697:true,
1697:false,
1698:true,
1698:false,
1699:true,
1699:false,
1700:true,
1700:false,
1701:true,
1701:false,
1702:true,
1702:false,
1703:true,
1703:false,
1704:true,
1704:false,
1705:true,
1705:false,
1706:true,
1706:false,
1707:true,
1707:false,
1708:true,
1708:false,
1709:true,
1709:false,
1710:true,
1710:false,
1711:true,
1711:false,
1712:true,
1712:false,
1713:true,
1713:false,
1714:true,
1714:false,
1715:true,
1715:false,
1716:true,
1716:false,
1717:true,
1717:false,
1718:true,
1718:false,
1719:true,
1719:false,
1720:true,
1720:false,
1721:true,
1721:false,
1722:true,
1722:false,
1723:true,
1723:false,
1724:true,
1724:false,
1725:true,
1726:true,
1726:false,
1725:false,
1727:true,
1727:false,
1728:true,
1728:false,
1729:true,
1729:false,
1730:true,
1730:false,
1731:true,
1731:false,
1732:true,
1732:false,
1733:true,
1733:false,
1734:true,
1734:false,
1735:true,
1735:false,
1736:true,
1736:false,
1737:true,
1737:false,
1738:true,
1738:false,
1739:true,
1739:false,
1740:true,
1740:false,
1741:true,
1741:false,
1742:true,
1742:false,
1743:true,
1743:false,
1744:true,
1744:false,
1745:true,
1745:false,
1746:true,
1746:false,
1747:true,
1747:false,
1748:true,
1748:false,
1749:true,
1749:false,
1750:true,
1750:false,
1751:true,
1751:false,
1752:true,
1752:false,
1753:true,
1753:false,
1754:true,
1754:false,
1755:true,
1755:false,
1756:true,
1756:false,
1757:true,
1757:false,
1758:true,
1758:false,
1759:true,
1759:false,
1760:true,
1760:false,
1761:true,
1761:false,
1762:true,
1762:false,
1763:true,
1763:false,
1764:true,
1764:false,
1765:true,
1765:false,
1766:true,
1766:false,
1767:true,
1767:false,
1768:true,
1768:false,
1769:true,
1769:false,
1770:true,
1770:false,
1771:true,
1771:false,
1772:true,
1772:false,
1773:true,
1773:false,
1774:true,
1774:false,
1775:true,
1775:false,
1776:true,
1776:false,
1777:true,
1777:false,
1778:true,
1778:false,
1779:true,
1779:false,
1780:true,
1780:false,
1781:true,
1781:false,
1782:true,
1782:false,
1783:true,
1783:false,
1784:true,
1784:false,
1785:true,
1785:false,
1786:true,
1786:false,
1787:true,
1787:false,
1788:true,
1788:false,
1789:true,
1789:false,
1790:true,
1790:false,
1791:true,
1791:false,
1792:true,
1792:false,
1793:true,
1793:false,
1794:true,
1794:false,
1795:true,
1795:false,
1796:true,
1796:false,
1797:true,
1797:false,
1798:true,
1798:false,
1799:true,
1799:false,
1800:true,
1800:false,
1801:true,
1801:false,
1802:true,
1802:false,
1803:true,
1803:false,
1804:true,
1804:false,
1805:true,
1805:false,
1806:true,
1806:false,
1807:true,
1807:false,
1808:true,
1808:false,
1809:true,
1809:false,
1810:true,
1810:false,
1811:true,
1811:false,
1812:true,
1812:false,
1813:true,
1813:false,
1814:true,
1814:false,
1815:true,
1815:false,
1816:true,
1816:false,
1817:true,
1817:false,
1818:true,
1818:false,
1819:true,
1819:false,
1820:true,
1820:false,
1821:true,
1821:false,
1822:true,
1822:false,
1823:true,
1823:false,
1824:true,
1824:false,
1825:true,
1825:false,
1826:true,
1826:false,
1827:true,
1827:false,
1828:true,
1828:false,
1829:true,
1829:false,
1830:true,
1830:false,
1831:true,
1831:false,
1832:true,
1832:false,
1833:true,
1833:false,
1834:true,
1834:false,
1835:true,
1835:false,
1836:true,
1836:false,
1837:true,
1837:false,
1838:true,
1838:false,
1839:true,
1839:false,
1840:true,
1840:false,
1841:true,
1841:false,
1842:true,
1842:false,
1843:true,
1843:false,
1844:true,
1844:false,
1845:true,
1845:false,
1846:true,
1846:false,
1847:true,
1847:false,
1848:true,
1848:false,
1849:true,
1849:false,
1850:true,
1850:false,
1851:true,
1851:false,
1852:true,
1852:false,
1853:true,
1853:false,
1854:true,
1854:false,
1855:true,
1855:false,
1856:true,
1856:false,
1857:true,
1857:false,
1858:true,
1858:false,
1859:true,
1859:false,
1860:true,
1860:false,
1861:true,
1861:false,
1862:true,
1862:false,
1863:true,
1863:false,
1864:true,
1864:false,
1865:true,
1865:false,
1866:true,
1866:false,
1867:true,
1867:false,
1868:true,
1868:false,
1869:true,
1869:false,
1870:true,
1870:false,
1871:true,
1871:false,
1872:true,
1872:false,
1873:true,
1873:false,
1874:true,
1874:false,
1875:true,
1875:false,
1876:true,
1876:false,
1877:true,
1877:false,
1878:true,
1878:false,
1879:true,
1879:false,
1880:true,
1880:false,
1881:true,
1881:false,
1882:true,
1882:false,
1883:true,
1883:false,
1884:true,
1884:false,
1885:true,
1885:false,
1886:true,
1886:false,
1887:true,
1887:false,
1888:true,
1889:true,
1889:false,
1890:true,
1890:false,
1891:true,
1891:false,
1888:false,
1892:true,
1892:false,
1893:true,
1894:true,
1894:false,
1895:true,
1895:false,
1896:true,
1896:false,
1897:true,
1897:false,
1898:true,
1898:false,
1893:false,
1899:true,
1899:false,
1900:true,
1901:true,
1901:false,
1902:true,
1902:false,
1903:true,
1903:false,
1900:false,
1904:true,
1904:false,
1905:true,
1906:true,
1906:false,
1907:true,
1907:false,
1908:true,
1908:false,
1909:true,
1909:false,
1910:true,
1910:false,
1911:true,
1911:false,
1912:true,
1912:false,
1913:true,
1913:false,
1914:true,
1914:false,
1915:true,
1915:false,
1916:true,
1916:false,
1917:true,
1917:false,
1918:true,
1918:false,
1919:true,
1919:false,
1920:true,
1920:false,
1921:true,
1921:false,
1922:true,
1922:false,
1923:true,
1923:false,
1924:true,
1924:false,
1925:true,
1925:false,
1926:true,
1926:false,
1927:true,
1927:false,
1905:false,
1928:true,
1928:false,
1929:true,
1929:false,
1930:true,
1930:false,
1931:true,
1932:true,
1932:false,
1933:true,
1933:false,
1934:true,
1934:false,
1935:true,
1935:false,
1936:true,
1936:false,
1937:true,
1937:false,
1938:true,
1938:false,
1939:true,
1939:false,
1931:false,
1940:true,
1941:true,
1940:false,
1942:true,
1941:false,
1943:true,
1944:true,
1944:false,
1943:false,
1945:true,
1945:false,
1946:true,
1946:false,
1947:true,
1947:false,
1948:true,
1948:false,
1949:true,
1949:false,
1950:true,
1950:false,
1951:true,
1951:false,
1952:true,
1952:false,
1953:true,
1953:false,
1954:true,
1954:false,
1955:true,
1955:false,
1956:true,
1956:false,
1957:true,
1957:false,
1958:true,
1958:false,
1959:true,
1959:false,
1960:true,
1960:false,
1961:true,
1961:false,
1962:true,
1962:false,
1963:true,
1963:false,
1964:true,
1964:false,
1965:true,
1965:false,
1966:true,
1966:false,
1967:true,
1967:false,
1968:true,
1968:false,
1969:true,
1969:false,
1970:true,
1970:false,
1971:true,
1971:false,
1972:true,
1972:false,
1973:true,
1973:false,
1974:true,
1974:false,
1975:true,
1975:false,
1976:true,
1976:false,
1977:true,
1977:false,
1978:true,
1978:false,
1942:false,
1979:true,
1979:false,
1980:true,
1981:true,
1981:false,
1982:true,
1982:false,
1983:true,
1983:false,
1984:true,
1984:false,
1985:true,
1985:false,
1986:true,
1986:false,
1987:true,
1987:false,
1988:true,
1988:false,
1989:true,
1989:false,
1990:true,
1990:false,
1991:true,
1991:false,
1992:true,
1992:false,
1993:true,
1993:false,
1994:true,
1994:false,
1995:true,
1995:false,
1996:true,
1996:false,
1997:true,
1997:false,
1998:true,
1998:false,
1999:true,
1999:false,
2000:true,
2000:false,
2001:true,
2001:false,
2002:true,
2002:false,
2003:true,
2003:false,
2004:true,
2004:false,
2005:true,
2005:false,
2006:true,
2006:false,
2007:true,
2007:false,
2008:true,
2008:false,
2009:true,
2010:true,
2011:true,
2011:false,
2010:false,
2012:true,
2012:false,
2009:false,
2013:true,
2013:false,
1980:false,
2014:true,
2014:false,
2015:true,
2016:true,
2016:false,
2017:true,
2017:false,
2018:true,
2018:false,
2019:true,
2019:false,
2020:true,
2020:false,
2021:true,
2021:false,
2022:true,
2022:false,
2023:true,
2023:false,
2024:true,
2024:false,
2025:true,
2025:false,
2026:true,
2026:false,
2027:true,
2027:false,
2028:true,
2028:false,
2029:true,
2029:false,
2030:true,
2030:false,
2015:false,
2031:true,
2031:false,
2032:true,
2033:true,
2033:false,
2034:true,
2034:false,
2035:true,
2035:false,
2036:true,
2036:false,
2037:true,
2038:true,
2037:false,
2038:false,
2039:true,
2039:false,
2040:true,
2040:false,
2041:true,
2042:true,
2042:false,
2041:false,
2043:true,
2043:false,
2044:true,
2044:false,
2045:true,
2045:false,
2046:true,
2047:true,
2047:false,
2046:false,
2048:true,
2048:false,
2032:false,
2049:true,
2049:false,
2050:true,
2051:true,
2051:false,
2052:true,
2052:false,
2053:true,
2053:false,
2054:true,
2054:false,
2055:true,
2055:false,
2056:true,
2056:false,
2057:true,
2058:true,
2058:false,
2057:false,
2059:true,
2059:false,
2060:true,
2060:false,
2061:true,
2061:false,
2062:true,
2062:false,
2063:true,
2050:false,
2064:true,
2064:false,
2065:true,
2063:false,
2066:true,
2067:true,
2068:true,
2069:true,
2070:true,
2071:true,
2072:true,
2073:true,
2074:true,
2075:true,
2076:true,
2077:true,
2078:true,
2079:true,
2080:true,
2081:true,
2082:true,
2083:true,
2084:true,
2085:true,
2086:true,
2087:true,
2088:true,
2089:true,
2090:true,
2091:true,
2092:true,
2093:true,
2094:true,
2095:true,
2096:true,
2097:true,
2098:true,
2099:true,
2100:true,
2101:true,
2102:true,
2103:true,
2104:true,
2105:true,
2106:true,
2107:true,
2108:true,
2109:true,
2110:true,
2111:true,
2112:true,
2113:true,
2114:true,
2115:true,
2116:true,
2117:true,
2118:true,
2119:true,
2120:true,
2121:true,
2122:true,
2123:true,
2124:true,
2125:true,
2126:true,
2127:true,
2128:true,
2129:true,
2130:true,
2131:true,
2132:true,
2133:true,
2134:true,
2135:true,
2136:true,
2137:true,
2138:true,
2139:true,
2140:true,
2141:true,
2142:true,
2143:true,
2144:true,
2145:true,
2146:true,
2147:true,
2148:true,
2149:true,
2150:true,
2151:true,
2152:true,
2153:true,
2154:true,
2155:true,
2156:true,
2157:true,
2158:true,
2159:true,
2160:true,
2161:true,
2162:true,
2163:true,
2164:true,
2165:true,
2166:true,
2167:true,
2168:true,
2169:true,
2170:true,
2171:true,
2172:true,
2173:true,
2174:true,
2175:true,
2176:true,
2177:true,
2178:true,
2179:true,
2180:true,
2181:true,
2182:true,
2183:true,
2184:true,
2185:true,
2186:true,
2187:true,
2188:true,
2189:true,
2190:true,
2191:true,
2192:true,
2193:true,
2194:true,
2195:true,
2196:true,
2197:true,
2198:true,
2199:true,
2200:true,
2201:true,
2202:true,
2203:true,
2204:true,
2205:true,
2206:true,
2207:true,
2208:true,
2209:true,
2210:true,
2211:true,
2212:true,
2213:true,
2214:true,
2215:true,
2216:true,
2217:true,
2218:true,
2219:true,
2220:true,
2221:true,
2222:true,
2223:true,
2224:true,
2225:true,
2226:true,
2227:true,
2228:true,
2229:true,
2230:true,
2231:true,
2232:true,
2233:true,
2234:true,
2235:true,
2236:true,
2237:true,
2238:true,
2239:true,
2240:true,
2241:true,
2242:true,
2243:true,
2244:true,
2245:true,
2246:true,
2247:true,
2248:true,
2249:true,
2250:true,
2251:true,
2252:true,
2253:true,
2254:true,
2255:true,
2256:true,
2257:true,
2258:true,
2259:true,
2260:true,
2261:true,
2262:true,
2263:true,
2264:true,
2265:true,
2266:true,
2267:true,
2268:true,
2269:true,
2270:true,
2271:true,
2272:true,
2273:true,
2274:true,
2275:true,
2276:true,
2277:true,
2278:true,
2279:true,
2280:true,
2281:true,
2282:true,
2283:true,
2284:true,
2285:true,
2286:true,
2287:true,
2288:true,
2289:true,
2290:true,
2291:true,
2292:true,
2293:true,
2294:true,
2295:true,
2296:true,
2297:true,
2298:true,
2299:true,
2300:true,
2301:true,
2302:true,
2303:true,
2304:true,
2305:true,
2306:true,
2307:true,
2308:true,
2309:true,
2310:true,
2311:true,
2312:true,
2313:true,
2314:true,
2315:true,
2316:true,
2317:true,
2318:true,
2319:true,
2320:true,
2321:true,
2322:true,
2323:true,
2324:true,
2325:true,
2326:true,
2327:true,
2328:true,
2329:true,
2330:true,
2331:true,
2332:true,
2333:true,
2334:true,
2335:true,
2336:true,
2337:true,
2338:true,
2339:true,
2340:true,
2341:true,
2342:true,
2343:true,
2344:true,
2345:true,
2346:true,
2347:true,
2348:true,
2349:true,
2350:true,
2351:true,
2352:true,
2353:true,
2354:true,
2355:true,
2356:true,
2357:true,
2358:true,
2359:true,
2360:true,
2361:true,
2362:true,
2363:true,
2364:true,
2365:true,
2366:true,
2367:true,
2368:true,
2369:true,
2370:true,
2371:true,
2372:true,
2373:true,
2374:true,
2375:true,
2376:true,
2377:true,
2378:true,
2379:true,
2380:true,
2381:true,
2382:true,
2383:true,
2384:true,
2385:true,
2386:true,
2387:true,
2388:true,
2389:true,
2390:true,
2391:true,
2392:true,
2393:true,
2394:true,
2395:true,
2396:true,
2397:true,
2398:true,
2399:true,
2400:true,
2401:true,
2402:true,
2403:true,
2404:true,
2405:true,
2406:true,
2407:true,
2408:true,
2409:true,
2410:true,
2411:true,
2412:true,
2413:true,
2414:true,
2415:true,
2416:true,
2417:true,
2418:true,
2065:false,
2419:true,
2420:true,
2421:true,
2422:true,
2423:true,
2424:true,
2425:true,
2426:true,
2427:true,
2428:true,
2429:true,
2430:true,
2431:true,
2432:true,
2433:true,
2425:false,
2434:true,
2435:true,
2436:true,
2437:true,
2438:true,
2439:true,
2440:true,
2441:true,
2442:true,
2443:true,
2444:true,
2445:true,
2446:true,
2447:true,
2448:true,
2449:true,
2450:true,
2451:true,
2452:true,
2453:true,
2454:true,
2455:true,
2456:true,
2457:true,
2458:true,
2459:true,
2460:true,
2461:true,
2462:true,
2463:true,
2464:true,
2465:true,
2466:true,
2467:true,
2468:true,
2469:true,
2470:true,
2471:true,
2472:true,
2473:true,
2474:true,
2475:true,
2476:true,
2477:true,
2478:true,
2479:true,
2480:true,
2481:true,
2482:true,
2483:true,
2484:true,
2485:true,
2486:true,
2487:true,
2488:true,
2489:true,
2490:true,
2491:true,
2492:true,
2493:true,
2494:true,
2495:true,
2496:true,
2497:true,
2498:true,
2499:true,
2500:true,
2501:true,
2502:true,
2503:true,
2504:true,
2505:true,
2506:true,
2507:true,
2508:true,
2509:true,
2510:true,
2511:true,
2512:true,
2513:true,
2514:true,
2515:true,
2516:true,
2517:true,
2518:true,
2519:true,
2520:true,
2521:true,
2522:true,
2523:true,
2524:true,
2525:true,
2526:true,
2527:true,
2528:true,
2529:true,
2530:true,
2531:true,
2532:true,
2533:true,
2534:true,
2535:true,
2536:true,
2537:true,
2538:true,
2539:true,
2540:true,
2541:true,
2542:true,
2543:true,
2544:true,
2545:true,
2546:true,
2547:true,
2548:true,
2549:true,
2550:true,
2551:true,
2552:true,
2553:true,
2554:true,
2555:true,
2556:true,
2557:true,
2558:true,
2559:true,
2560:true,
2561:true,
2562:true,
2563:true,
2564:true,
2565:true,
2566:true,
2567:true,
2568:true,
2569:true,
2570:true,
2571:true,
2572:true,
2573:true,
2574:true,
2575:true,
2576:true,
2577:true,
2578:true,
2579:true,
2580:true,
2581:true,
2582:true,
2583:true,
2584:true,
2585:true,
2586:true,
2587:true,
2588:true,
2589:true,
2590:true,
2591:true,
2592:true,
2593:true,
2594:true,
2595:true,
2596:true,
2597:true,
2598:true,
2599:true,
2600:true,
2601:true,
2602:true,
2603:true,
2604:true,
2605:true,
2606:true,
2607:true,
2608:true,
2609:true,
2610:true,
2611:true,
2612:true,
2613:true,
2614:true,
2615:true,
2616:true,
2617:true,
2618:true,
2619:true,
2620:true,
2621:true,
2622:true,
2623:true,
2624:true,
2625:true,
2626:true,
2627:true,
2628:true,
2629:true,
2630:true,
2631:true,
2632:true,
2633:true,
2634:true,
2635:true,
2636:true,
2637:true,
2638:true,
2639:true,
2640:true,
2641:true,
2642:true,
2643:true,
2644:true,
2645:true,
2646:true,
2647:true,
2648:true,
2649:true,
2650:true,
2651:true,
2652:true,
2653:true,
2654:true,
2655:true,
2656:true,
2657:true,
2658:true,
2659:true,
2660:true,
2661:true,
2662:true,
2663:true,
2664:true,
2665:true,
2666:true,
2667:true,
2668:true,
2669:true,
2670:true,
2671:true,
2672:true,
2673:true,
2674:true,
2675:true,
2676:true,
2677:true,
2678:true,
2679:true,
2680:true,
2681:true,
2682:true,
2683:true,
2684:true,
2685:true,
2686:true,
2687:true,
2688:true,
2689:true,
2690:true,
2691:true,
2692:true,
2693:true,
2694:true,
2695:true,
2696:true,
2697:true,
2698:true,
2699:true,
2700:true,
2701:true,
2702:true,
2703:true,
2704:true,
2705:true,
2706:true,
2707:true,
2708:true,
2709:true,
2710:true,
2711:true,
2712:true,
2713:true,
2714:true,
2715:true,
2716:true,
2717:true,
2718:true,
2719:true,
2720:true,
2721:true,
2722:true,
2723:true,
2724:true,
2725:true,
2726:true,
2727:true,
2728:true,
2729:true,
2730:true,
2731:true,
2732:true,
2733:true,
2734:true,
2735:true,
2736:true,
2737:true,
2738:true,
2739:true,
2740:true,
2741:true,
2742:true,
2743:true,
2744:true,
2745:true,
2746:true,
2747:true,
2748:true,
2749:true,
2750:true,
2751:true,
2752:true,
2753:true,
2754:true,
2755:true,
2756:true,
2757:true,
2758:true,
2759:true,
2760:true,
2761:true,
2762:true,
2763:true,
2764:true,
2765:true,
2766:true,
2767:true,
2768:true,
2769:true,
2770:true,
2771:true,
2772:true,
2773:true,
2774:true,
2775:true,
2776:true,
2777:true,
2778:true,
2779:true,
2780:true,
2781:true,
2782:true,
2783:true,
2784:true,
2785:true,
2786:true,
2787:true,
2788:true,
2789:true,
2790:true,
2791:true,
2792:true,
2793:true,
2794:true,
2795:true,
2796:true,
2797:true,
2798:true,
2799:true,
2800:true,
2801:true,
2802:true,
2803:true,
2804:true,
2805:true,
2806:true,
2807:true,
2808:true,
2809:true,
2810:true,
2811:true,
2812:true,
2813:true,
2814:true,
2815:true,
2816:true,
2817:true,
2434:false,
2818:true,
2819:true,
2820:true,
2821:true,
2822:true,
2823:true,
2820:false,
2824:true,
2825:true,
2826:true,
2827:true,
2828:true,
2829:true,
2830:true,
2831:true,
2832:true,
2833:true,
2834:true,
2835:true,
2836:true,
2837:true,
2838:true,
2839:true,
2840:true,
2841:true,
2842:true,
2843:true,
2844:true,
2845:true,
2846:true,
2847:true,
2848:true,
2849:true,
2850:true,
2851:true,
2852:true,
2853:true,
2854:true,
2855:true,
2856:true,
2857:true,
2858:true,
2859:true,
2860:true,
2861:true,
2862:true,
2863:true,
2864:true,
2865:true,
2866:true,
2867:true,
2868:true,
2869:true,
2870:true,
2871:true,
2872:true,
2873:true,
2874:true,
2875:true,
2876:true,
2877:true,
2878:true,
2879:true,
2880:true,
2881:true,
2882:true,
2883:true,
2884:true,
2885:true,
2886:true,
2887:true,
2888:true,
2889:true,
2890:true,
2891:true,
2892:true,
2893:true,
2894:true,
2895:true,
2896:true,
2897:true,
2898:true,
2899:true,
2900:true,
2901:true,
2902:true,
2903:true,
2904:true,
2905:true,
2906:true,
2907:true,
2908:true,
2909:true,
2910:true,
2911:true,
2912:true,
2913:true,
2914:true,
2915:true,
2916:true,
2917:true,
2918:true,
2919:true,
2920:true,
2921:true,
2922:true,
2923:true,
2924:true,
2925:true,
2926:true,
2927:true,
2928:true,
2929:true,
2930:true,
2931:true,
2932:true,
2933:true,
2934:true,
2935:true,
2936:true,
2937:true,
2938:true,
2939:true,
2940:true,
2941:true,
2942:true,
2943:true,
2944:true,
2945:true,
2946:true,
2947:true,
2948:true,
2949:true,
2950:true,
2951:true,
2952:true,
2953:true,
2954:true,
2955:true,
2956:true,
2957:true,
2958:true,
2959:true,
2960:true,
2961:true,
2962:true,
2963:true,
2964:true,
2965:true,
2966:true,
2967:true,
2968:true,
2969:true,
2970:true,
2971:true,
2972:true,
2973:true,
2974:true,
2975:true,
2976:true,
2977:true,
2978:true,
2979:true,
2980:true,
2981:true,
2982:true,
2983:true,
2984:true,
2985:true,
2986:true,
2987:true,
2988:true,
2989:true,
2990:true,
2991:true,
2992:true,
2993:true,
2994:true,
2995:true,
2996:true,
2997:true,
2998:true,
2999:true,
3000:true,
3001:true,
3002:true,
3003:true,
3004:true,
3005:true,
3006:true,
3007:true,
3008:true,
3009:true,
3010:true,
3011:true,
3012:true,
3013:true,
3014:true,
3015:true,
3016:true,
3017:true,
3018:true,
3019:true,
3020:true,
3021:true,
3022:true,
3023:true,
3024:true,
3025:true,
3026:true,
3027:true,
3028:true,
3029:true,
3030:true,
3031:true,
3032:true,
3033:true,
3034:true,
3035:true,
3036:true,
3037:true,
3038:true,
3039:true,
3040:true,
3041:true,
3042:true,
3043:true,
3044:true,
3045:true,
3046:true,
3047:true,
3048:true,
3049:true,
3050:true,
3051:true,
3052:true,
3053:true,
3054:true,
3055:true,
3056:true,
3057:true,
3058:true,
3059:true,
3060:true,
3061:true,
3062:true,
3063:true,
3064:true,
3065:true,
3066:true,
3067:true,
3068:true,
3069:true,
3070:true,
3070:false,
3069:false,
3068:false,
3067:false,
3066:false,
3065:false,
3064:false,
3063:false,
3062:false,
3061:false,
3060:false,
3059:false,
3058:false,
3057:false,
3056:false,
3055:false,
3054:false,
3053:false,
3052:false,
3051:false,
3050:false,
3049:false,
3048:false,
3047:false,
3046:false,
3045:false,
3044:false,
3043:false,
3042:false,
3041:false,
3040:false,
3039:false,
3038:false,
3037:false,
3036:false,
3035:false,
3034:false,
3033:false,
3032:false,
3031:false,
3030:false,
3029:false,
3028:false,
3027:false,
3026:false,
3025:false,
3024:false,
3023:false,
3022:false,
3021:false,
3020:false,
3019:false,
3018:false,
3017:false,
3016:false,
3015:false,
3014:false,
3013:false,
3012:false,
3011:false,
3010:false,
3009:false,
3008:false,
3007:false,
3006:false,
3005:false,
3004:false,
3003:false,
3002:false,
3001:false,
3000:false,
2999:false,
2998:false,
2997:false,
2996:false,
2995:false,
2994:false,
2993:false,
2992:false,
2991:false,
2990:false,
2989:false,
2988:false,
2987:false,
2986:false,
2985:false,
2984:false,
2983:false,
2982:false,
2981:false,
2980:false,
2979:false,
2978:false,
2977:false,
2976:false,
2975:false,
2974:false,
2973:false,
2972:false,
2971:false,
2970:false,
2969:false,
2968:false,
2967:false,
2966:false,
2965:false,
2964:false,
2963:false,
2962:false,
2961:false,
2960:false,
2959:false,
2958:false,
2957:false,
2956:false,
2955:false,
2954:false,
2953:false,
2952:false,
2951:false,
2950:false,
2949:false,
2948:false,
2947:false,
2946:false,
2945:false,
2944:false,
2943:false,
2942:false,
2941:false,
2940:false,
2939:false,
2938:false,
2937:false,
2936:false,
2935:false,
2934:false,
2933:false,
2932:false,
2931:false,
2930:false,
2929:false,
2928:false,
2927:false,
2926:false,
2925:false,
2924:false,
2824:false,
2923:false,
2922:false,
3071:true,
2921:false,
2920:false,
2919:false,
2918:false,
2917:false,
2916:false,
2915:false,
2914:false,
2913:false,
2912:false,
2911:false,
2910:false,
2909:false,
2908:false,
2907:false,
3071:false,
3072:true,
2906:false,
3073:true,
3073:false,
3074:true,
3074:false,
3075:true,
3075:false,
3076:true,
3076:false,
3077:true,
3077:false,
3078:true,
3078:false,
3079:true,
3079:false,
3080:true,
3072:false,
3081:true,
3081:false,
3082:true,
3083:true,
3083:false,
3080:false,
3084:true,
3084:false,
3085:true,
3085:false,
3086:true,
3086:false,
3087:true,
3087:false,
3082:false,
3088:true,
3088:false,
3089:true,
3090:true,
3090:false,
3091:true,
3091:false,
3092:true,
3092:false,
3089:false,
3093:true"""

        val operations = data.replace("\n", "").split(",").filter {
            it.isNotEmpty()
        }.map {
            it.split(":").let {
                it[0].toInt() to it[1].toBoolean()
            }
        }
        operations.fold(SnapshotIdSet.EMPTY) { prev, (value, op) ->
            assertTrue(prev.get(value) != op, "Error on bit $value, expected ${!op}, received $op")
            val result = if (op) prev.set(value) else prev.clear(value)
            result
        }
    }
}

private fun SnapshotIdSet.shouldBe(index: Int, value: Boolean): SnapshotIdSet {
    assertEquals(value, get(index), "Bit $index should be $value")
    return this
}
